A virtual machine (“VM”) is a software construct or the like operating on a computing device or the like (e.g., a host) for the purpose of providing an emulated machine or system. Typically, although not necessarily, the VM is an application or the like, and may be employed on the host to instantiate a use application or the like while at the same time isolating such use application from such host device or from other applications on such host. In one typical situation, the host can accommodate a plurality of deployed VMs, each VM performing some predetermined function by way of resources available from the host.
Notably, each VM as hosted on a computing device is for all intents and purposes a computing machine, although in virtual form, and thus represents itself as such both to the use application thereof and to the outside world. As an example, the VM and/or a use application thereof can and in fact do issue hardware requests for hardware resources of the VM, even though the VM might not in reality have such hardware resources. Instead, and as may be appreciated, such hardware requests are intercepted or otherwise redirected toward the host, and such host services such hardware requests based on the hardware resources thereof, typically with the requesting VM and/or use application thereof being none the wiser.
Typically, although not necessarily, a host deploys each VM thereof in a separate partition, address space, processing area, and/or the like. Such host may include a virtualization layer with a virtual machine monitor or the like that acts as an overseer application or hypervisor, where the virtualization layer oversees and/or otherwise manages supervisory aspects of each VM of the host, and acts as a possible link between each VM and the outside world. The hypervisor may be a separate application running in its own address space or may be integrated more closely with the host operating system, either directly or as an operating system extension of some sort, such as a device driver. Notably, the hypervisor of the host may intercept or otherwise redirect hardware requests that originate from each VM of the host and/or a use application thereof, and may at least assist in servicing the requests, again with the requesting VM and/or use application thereof being none the wiser.
Many computing systems comprise multiple processors. Processors in a uniprocessor or multiprocessor virtual machine environment may operate in a guest mode or in a hypervisor mode. When running in a guest mode, a processor uses virtual machine definitions to manage the virtual machine's guest operating system and applications, translating arguments and managing system resources without intervention from the hypervisor. From time to time, the guest operating system or applications may need system resources that must be managed by the hypervisor. As examples, the hypervisor may be required for error handling, system faults, intercepts for emulating devices, or interrupt handling. In these situations, the processor operates in a hypervisor mode.
In some systems, processors are virtualized. A virtual processor is a software construct or the like operating on a computing device or the like for the purpose of providing an emulated processor. Multiple virtual processors can be implemented on a single physical processor or on multiple physical processors. One technique used to partition a computer into a number of virtual machines is to multiplex more than one virtual processor on one or more physical processors.
In systems having multiple virtual processors, it is necessary to have a way to switch contexts from one virtual processor to another. Switching contexts between virtual processors is similar in some ways to switching threads that are multiplexed on a single physical processor in a traditional computing system. Hardware has developed over time to optimize the efficiency with which the context associated with a thread can be switched.
One way of implementing a context switch between two threads involves writing the state of the outgoing thread, including register values, to memory, reading in the (usually previously saved) state of the incoming thread, and resuming processing in the newly read state. There is a certain amount of overhead involved in all of the register accesses, memory reads, and memory writes associated with such a context switch.
One method of mitigating some of the overhead involved in switching contexts is the “lazy switch” in which some portions of the context are not written or read unless and until needed. One example of lazy switching has been used with respect to thread switching and floating point coprocessors. With lazy switching, the outgoing state of the floating point processor is not immediately saved upon switching threads. Only when a new thread accesses the floating point coprocessor is the old thread's state saved and the incoming thread's state loaded. By waiting for an actual floating point coprocessor access before changing contexts in the floating point coprocessor, some context switches are avoided completely. For example, suppose that a first thread is executing and has used the floating point coprocessor and so the first thread's context is loaded into the floating point coprocessor. If a second thread then executes but does not access the floating point coprocessor before a succeeding thread switch, the context of the second thread is never be loaded into the floating point coprocessor and the context of the first thread will remain loaded.
A virtual processor generally has a larger context than that associated with a thread. The context of a virtual processor generally involves several registers, some of which are not normally accessed frequently by an operating system. Some processor vendors have provided virtualization architectures having hardware assists to speed switching of some registers. Accesses to other registers have not been hardware optimized, and those registers are often slow to read and/or write.